package com.hardydou.framework.websocket.service;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.hardydou.framework.websocket.IWsService;
import com.hardydou.framework.websocket.UserSession;
import com.hardydou.framework.websocket.WsMessage;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ：hardy
 * @description：
 * @date ：Created in 2020/7/1
 * @Copyright ：Hardydou.com
 */
@Service
public class WsServiceImpl implements IWsService {

    static Log log = LogFactory.get(WsServiceImpl.class);
    private final static ConcurrentHashMap<String, UserSession> SID_SESSION = new ConcurrentHashMap<>();
    private final static ConcurrentHashMap<Long, String> UID_SID = new ConcurrentHashMap<>();


    @Override
    public void add(UserSession userSession) {
        SID_SESSION.put(userSession.getSession().getId(), userSession);
        UID_SID.put(userSession.getUserId(), userSession.getSession().getId());
    }

    @Override
    public void remove(UserSession userSession) {
        SID_SESSION.remove(userSession.getSession().getId());
        UID_SID.remove(userSession.getUserId());
    }

    @Override
    public UserSession findBySid(String sid) {
        return SID_SESSION.get(sid);
    }

    @Override
    public UserSession findByUid(Long uid) {
        return findBySid(UID_SID.get(uid));
    }

    @Override
    public void accept(WsMessage message) {
        Long fromUserId = message.getFromUserId();
        log.info("接收消息({}-{}),{},{}", fromUserId, message.getToUserId(), message.getType(), message.getTextData());
        send(message);
    }

    @Override
    public void send(WsMessage message) {
        Long toUid = message.getToUserId();
        UserSession userSession = findByUid(toUid);
        try {
            switch (message.getType()) {
                case TXT:
                    userSession.getSession().getBasicRemote().sendText(message.getTextData());
                    break;
                case BYTE:
                    userSession.getSession().getBasicRemote().sendBinary(message.getByteData());
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + message.getType());
            }
        } catch (IOException e) {
            log.error("网络异常（{}） ", toUid);
            remove(userSession);
        }
    }
}